﻿using System;
using System.Threading;

using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;

using SecretLabs.NETMF.Hardware.NetduinoPlus;

using Coding4Fun.Maelstrom.Common;
using Coding4Fun.Maelstrom.Hardware.Controllers;
using Coding4Fun.Maelstrom.Hardware.Diagnostics;
using Coding4Fun.Maelstrom.Hardware.WebServer;

namespace Coding4Fun.Maelstrom.Hardware
{
	public class Program
	{
		private const string NewLine = "\r\n";

		private static readonly Listener WebServer = new Listener();

		private static readonly GameStateAnimationController GameState = new GameStateAnimationController();
		private static readonly DamageController Damage = new DamageController();
		private static readonly ScoreController Score = new ScoreController();

		public static void Main()
		{
			// write your code here
			var nics = NetworkInterface.GetAllNetworkInterfaces();

			foreach (var nic in nics)
				Logger.WriteLine(nic.IPAddress);

			WebServer.RequestReceived += WebServerRequestReceived;
			WebServer.Start();

			var led = new OutputPort(Pins.ONBOARD_LED, false);

			GameState.ExecuteAction(new UrlData {GameStateAnimation = GameStateAnimation.Idle});

			while (true)
			{
				// Blink LED to show we're still responsive
				led.Write(true);
				Thread.Sleep(50);

				led.Write(false);
				Thread.Sleep(1000);
			}
		}

		private static void WebServerRequestReceived(Request request)
		{
			var start = DateTime.Now;
			Logger.WriteLine("Start: " + request.Url + " at " + DateTime.Now);

			try
			{
				var data = UrlHelper.ParseUrl(request.Url);

				var targetController = GetController(data);

				if (targetController != null)
				{
					targetController.ExecuteAction(data);
				}
			}
			catch (Exception ex0)
			{
				Logger.WriteLine(ex0.ToString());
			}

			request.SendResponse(NewLine);

			Logger.WriteLine("End: " + request.Url + " at " + DateTime.Now + " took: " + (DateTime.Now - start).Milliseconds);
		}

		public static IController GetController(UrlData data)
		{
			if (data.IsDamage)
				return Damage;

			if (data.IsScore)
				return Score;

			if (data.IsGameState)
				return GameState;

			// can assume invalid
			return null;
		}
	}
}